﻿using GylCSharpUtils.GSerializer.SpecialConverter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace GylCSharpUtils.Common.Base.SpecialConverter {

    public class SpecialConverterManager {
        private static Dictionary<Type, ASpecialConverter> dict_ObjType_Converter = new Dictionary<Type, ASpecialConverter>();
        private static Dictionary<Type, Type> dict_SerialType_ObjType = new Dictionary<Type, Type>();
        private static Dictionary<string, ASpecialConverter> dict_ObjTypeName_Converter = new Dictionary<string, ASpecialConverter>();
        private static SpecialConverterManager instance = new SpecialConverterManager();
        private SpecialConverterManager() {
            LoadSpecialConverters();
        }

        /// <summary>
        /// 加载专有序列化器
        /// </summary>
        private static void LoadSpecialConverters() {
            var types = Assembly.GetExecutingAssembly().GetTypes();
            foreach(var type in types) {
                if(!type.IsSubclassOf(typeof(ASpecialConverter)) || type.IsAbstract) continue;
                // 创建该类型专有的序列化器
                var serial = (ASpecialConverter)type.GetConstructor(new Type[] { }).Invoke(null);
                // 获取对应类型
                Type specialType = serial.SpecialType;
                // 获取专有类型的全限定名称
                string typeName = specialType.FullName;

                if(dict_ObjType_Converter.ContainsKey(specialType)) {
                    throw new Exception($"为类{typeName}配置了多个专有序列化工具");
                }
                dict_ObjType_Converter.Add(specialType, serial);
                dict_ObjTypeName_Converter.Add(typeName, serial);
                dict_SerialType_ObjType.Add(type, specialType);
            }
        }

        /// <summary>
        /// 获取所有的专有序列化器
        /// </summary>
        /// <returns></returns>
        public static List<ASpecialConverter> GetAllSpecialConverter() {
            return dict_ObjType_Converter.Select(kv => kv.Value).ToList();
        }

        public static ASpecialConverter GetSpecialConverter(string specialTypeName) {
            if(dict_ObjTypeName_Converter.ContainsKey(specialTypeName)) {
                return dict_ObjTypeName_Converter[specialTypeName];
            }
            return null;
        }
        public static ASpecialConverter GetSpecialConverter(Type specialType) {
            if(dict_ObjType_Converter.ContainsKey(specialType)) {
                return dict_ObjType_Converter[specialType];
            }
            return null;
        }
    }
}
